package cmd

import (
	"errors"
	"fmt"
	"github.com/kevinlisr/install-levault/conf"
	"github.com/kevinlisr/install-levault/service"
	"github.com/kevinlisr/install-levault/vari"
	"github.com/spf13/cobra"
)

// 二级命令
var minioCmd = &cobra.Command{
	Use:   "minio",
	Short: "minio [create/upload/download]",
	Long: `Creates the bucket with specified name
            use: minio create bucket -n testbucket
                 minio upload -u http://127.0.0.1:9000 -b testbucket -d /data/testdir`,
	RunE: func(cmd *cobra.Command, args []string) error {
		vari.Logger.Info(fmt.Sprintf("you entered bucketName: %s accessKey: %s EndpointUrl: %s \n", BucketName, AccessKeyID, EndpointUrl))
		return nil
	},
}

// 三级命令
var createBucketCmd = &cobra.Command{
	Use:   "create",
	Short: "create",
	Long:  `create bucket `,
	RunE: func(cmd *cobra.Command, args []string) error {
		// 初始化配置文件（可直接使用测试用例的代码）
		//if err := conf.LoadConfigFromToml(ConfFile); err != nil {
		//	return err
		//}
		// 初始化全局变量
		if err := loadGlobalConfig(ConfType, Format); err != nil {
			return fmt.Errorf("LoadGlobalConfig failed %s\n", ConfFile)
		}
		conf := conf.C()

		vari.Logger.Info(fmt.Sprintf("The endpointurl: %s bucket: %s \n", conf.Minio.EndpointUrl, conf.Minio.BucketName))

		// Get Minio Client
		minioClient, err := conf.Minio.Client()
		if err != nil {
			vari.Logger.Error(fmt.Sprintf("Get Minio %s Client failed \n", conf.Minio.EndpointUrl))
			return fmt.Errorf("Get Minio %s Client failed \n", conf.Minio.EndpointUrl)
		}
		vari.Logger.Info(fmt.Sprintf("Get Minio %s Client success \n", conf.Minio.EndpointUrl))

		minioExec := service.NewMinioExecutor(minioClient)
		if BucketName != "" {
			conf.Minio.BucketName = BucketName
		}
		err = minioExec.CreateBucket(conf.Minio.BucketName, conf.Minio.Location)
		if err != nil {
			vari.Logger.Error(fmt.Sprintf("Create Minio Bucket failed endpointurl: %s, bucket: %s\n", conf.Minio.EndpointUrl, conf.Minio.BucketName))
			return fmt.Errorf("Create Minio Bucket failed endpointurl: %s, bucket: %s\n", conf.Minio.EndpointUrl, conf.Minio.BucketName)
		}
		vari.Logger.Info(fmt.Sprintf("Create Minio Bucket failed endpointurl: %s, bucket: %s\n", conf.Minio.EndpointUrl, conf.Minio.BucketName))
		return nil
	},
}

// 三级命令
var uploadCmd = &cobra.Command{
	Use:   "upload",
	Short: "upload",
	Long:  `upload file to minio`,
	RunE: func(cmd *cobra.Command, args []string) error {
		// 初始化全局变量
		if err := loadGlobalConfig(ConfType, Format); err != nil {
			return err
		}
		conf := conf.C()

		if BucketName != "" {
			conf.Minio.BucketName = BucketName
		}
		if EndpointUrl != "" {
			conf.Minio.EndpointUrl = EndpointUrl
		}
		vari.Logger.Info(fmt.Sprintf("The bucket: %s endpointurl: %s\n", conf.Minio.BucketName, conf.Minio.EndpointUrl))

		minioClient, err := conf.Minio.Client()
		if err != nil {
			vari.Logger.Error(fmt.Sprintf("Get Minio %s Client failed \n", conf.Minio.EndpointUrl))
			return fmt.Errorf("Get Minio %s Client failed \n", conf.Minio.EndpointUrl)
		}
		vari.Logger.Info(fmt.Sprintf("Get Minio %s Client success \n", conf.Minio.EndpointUrl))

		minioExec := service.NewMinioExecutor(minioClient)
		err = minioExec.UploadFile(conf.Minio.BucketName, conf.Minio.PathDir)
		if err != nil {
			vari.Logger.Error(fmt.Sprintf("Upload file to Minio Bucket failed endpointurl: %s, bucket: %s\n", conf.Minio.EndpointUrl, conf.Minio.BucketName))
			return fmt.Errorf("Upload file to Minio Bucket failed endpointurl: %s, bucket: %s\n", conf.Minio.EndpointUrl, conf.Minio.BucketName)
		}
		vari.Logger.Info(fmt.Sprintf("Upload file to Minio Bucket failed endpointurl: %s, bucket: %s\n", conf.Minio.EndpointUrl, conf.Minio.BucketName))
		return nil
	},
}

func init() {
	RootCmd.AddCommand(minioCmd)
	minioCmd.AddCommand(createBucketCmd, uploadCmd)
	createBucketCmd.PersistentFlags().StringVarP(&ConfType, "config-type", "t", "file", "the service config type [file/env/etcd], minio create -t file ")
	createBucketCmd.PersistentFlags().StringVarP(&ConfFile, "config-file", "f", "etc/config.toml", "the service config from file,minio create -f /root/config.toml")
	createBucketCmd.PersistentFlags().StringVarP(&BucketName, "bucket-name", "b", "test", "minio create -b test")
	createBucketCmd.PersistentFlags().StringVarP(&EndpointUrl, "endpoint-url", "u", "http://127.0.0.1:9000", "minio create -u http://127.0.0.1:9000")
	uploadCmd.PersistentFlags().StringVarP(&ConfType, "config-type", "t", "file", "the service config type [file/env/etcd], minio create -t file ")
	uploadCmd.PersistentFlags().StringVarP(&ConfFile, "config-file", "f", "etc/config.toml", "the service config from file,minio create -f /root/config.toml")
	uploadCmd.PersistentFlags().StringVarP(&PathDir, "path-dir", "d", "/root/testfile", "minio upload -d /root/testfile")
	uploadCmd.PersistentFlags().StringVarP(&BucketName, "bucket-name", "b", "test", "minio create -b test")
	uploadCmd.PersistentFlags().StringVarP(&EndpointUrl, "endpoint-url", "u", "http://127.0.0.1:9000", "minio create -u http://127.0.0.1:9000")
}

// config 为全局变量, 只需要load 即可全局可用户
func loadGlobalConfig(configType, format string) error {
	// 配置加载
	switch configType {
	case "file":
		if format == "yaml" || format == "" {
			vari.Logger.Info(fmt.Sprintf("file type is: %s", ConfFile))
			_ = conf.Viper(ConfFile)
		} else {
			vari.Logger.Info(fmt.Sprintf("file type is: %s\n", ConfFile))
			err := conf.LoadConfigFromToml(ConfFile)
			if err != nil {
				return err
			}
		}

	case "env":
		err := conf.LoadConfigFromEnv()
		if err != nil {
			return fmt.Errorf("loadConfigFromEnv failed %s", err.Error())
		}
	default:
		return errors.New("unknown config type")
	}

	return nil
}
